package com.yn.xr.common.util;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

public class ImageUtils {

	private ImageUtils() {
	}

	private BufferedImage image = null;

	public void load(File imageFile) throws IOException {
		image = ImageIO.read(imageFile);
	}

	public void loadImage(BufferedImage image) throws IOException {
		this.image = image;
	}

	public void loaBytes(byte[] bytes) throws IOException {
		image = ImageIO.read(new ByteArrayInputStream(bytes));
	}

	public int getImageWidth() {
		return image.getWidth();
	}

	public BufferedImage getImg() {
		return image;
	}

	public int getImageHeight() {
		return image.getHeight();
	}

	/**
	 * 切图，
	 * 
	 * @param x
	 *            开始位置
	 * @param y
	 * @param tarWidth
	 *            宽
	 * @param tarHeight
	 *            高
	 * @throws FileNotFoundException
	 */
	public void cutTo(int x, int y, int tarWidth, int tarHeight)
			throws FileNotFoundException {
		if (image == null) {
			throw new FileNotFoundException(
					"image file not be load.please execute 'load' function agin.");
		}

		int iSrcWidth = getImageWidth();
		int iSrcHeight = getImageHeight();

		if (iSrcWidth < tarWidth || iSrcHeight < tarHeight) {

			throw new RuntimeException("source image size too small.");
		}

		double dSrcScale = iSrcWidth * 1.0 / iSrcHeight;
		double dDstScale = tarWidth * 1.0 / tarHeight;

		int iDstLeft, iDstTop, iDstWidth, iDstHeight;
		if (dDstScale > dSrcScale) {
			iDstWidth = iSrcWidth;
			iDstHeight = (int) (iDstWidth * 1.0 / dDstScale);
		} else {
			iDstHeight = iSrcHeight;
			iDstWidth = (int) (iDstHeight * dDstScale);
		}
		iDstLeft = (iSrcWidth - iDstWidth) / 2;
		iDstTop = (iSrcHeight - iDstHeight) / 2;

		this.image = image.getSubimage(x, y, tarWidth, tarHeight);

	}

	/**
	 * 缩放
	 * 
	 * @param tarWidth
	 *            宽
	 * @param tarHeight
	 *            高
	 */
	public void zoomTo(int tarWidth, int tarHeight) {
		BufferedImage tagImage = new BufferedImage(tarWidth, tarHeight,BufferedImage.TYPE_INT_RGB);
		Image image = this.image.getScaledInstance(tarWidth, tarHeight,Image.SCALE_REPLICATE);
		Graphics g = tagImage.getGraphics();
		g.drawImage(image, 0, 0, null);
		g.dispose();
		this.image = tagImage;

	}

	/**
	 * 保存
	 * 
	 * @param fileName
	 * @param formatName
	 * @throws IOException
	 */
	public void save(String fileName, String formatName) throws IOException {
		FileOutputStream out = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ImageIO.write(this.image, formatName, bos);
			out = new FileOutputStream(fileName);
			out.write(bos.toByteArray());
		} finally {
			if (out != null)
				out.close();
		}
	}

	/**
	 * 加载
	 */
	public static boolean zoomImage(String srcFile, String dstFile, int width,
			int height, String formatName) {
		try {
			ImageUtils zoom = new ImageUtils();
			zoom.load(new File(srcFile));
			zoom.zoomTo(width, height);
			zoom.save(dstFile, formatName);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}

		return true;
	}

	private static ImageUtils fromImageFile(File file) throws IOException {
		ImageUtils utils = new ImageUtils();
		utils.load(file);
		return utils;
	}

	private static ImageUtils fromImageFile(BufferedImage image)
			throws IOException {
		ImageUtils utils = new ImageUtils();
		utils.loadImage(image);
		return utils;
	}

	private static ImageUtils fromImageFile(byte[] bytes) throws IOException {
		ImageUtils utils = new ImageUtils();
		utils.loaBytes(bytes);
		return utils;
	}

	/**
	 * 加载
	 * 
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	public static ImageUtils load(String fileName) throws IOException {
		File file = new File(fileName);
		return fromImageFile(file);
	}

	public static ImageUtils loadFile(File file) throws IOException {
		return fromImageFile(file);
	}

	public static ImageUtils load(BufferedImage image) throws IOException {
		return fromImageFile(image);
	}

	public static ImageUtils loadBytes(byte[] bytes) throws IOException {
		return fromImageFile(bytes);
	}
}
